/**
 * AchievementSystem - 成就系统
 * 管理游戏成就的解锁、进度跟踪和奖励发放
 */

import { 
  AchievementCategory,
  type Achievement, 
  type AchievementCondition, 
  type AchievementReward 
} from './StorageManager'

/**
 * 游戏统计数据接口
 */
export interface GameStatistics {
  totalScore: number
  totalDistance: number
  totalCoins: number
  gamesPlayed: number
  powerUpsCollected: number
  charactersUnlocked: number
  maxSurvivalTime: number
  highestScore: number
  longestDistance: number
  perfectRuns: number
  consecutiveJumps: number
  slidingDistance: number
}

/**
 * 成就事件类型
 */
export enum AchievementEventType {
  GAME_START = 'game_start',
  GAME_END = 'game_end',
  SCORE_ACHIEVED = 'score_achieved',
  DISTANCE_REACHED = 'distance_reached',
  COIN_COLLECTED = 'coin_collected',
  POWERUP_COLLECTED = 'powerup_collected',
  CHARACTER_UNLOCKED = 'character_unlocked',
  PERFECT_RUN = 'perfect_run',
  SURVIVAL_TIME = 'survival_time',
  JUMP_PERFORMED = 'jump_performed',
  SLIDE_PERFORMED = 'slide_performed'
}

/**
 * 成就事件数据
 */
export interface AchievementEvent {
  type: AchievementEventType
  value: number
  metadata?: Record<string, any>
}

/**
 * 成就解锁结果
 */
export interface AchievementUnlockResult {
  achievement: Achievement
  isNewlyUnlocked: boolean
  reward: AchievementReward
}

/**
 * 成就系统类
 */
export class AchievementSystem {
  private achievements: Map<string, Achievement> = new Map()
  private statistics: GameStatistics
  private eventListeners: Map<AchievementEventType, ((event: AchievementEvent) => void)[]> = new Map()

  constructor(initialStatistics?: Partial<GameStatistics>) {
    this.statistics = {
      totalScore: 0,
      totalDistance: 0,
      totalCoins: 0,
      gamesPlayed: 0,
      powerUpsCollected: 0,
      charactersUnlocked: 1, // 默认角色已解锁
      maxSurvivalTime: 0,
      highestScore: 0,
      longestDistance: 0,
      perfectRuns: 0,
      consecutiveJumps: 0,
      slidingDistance: 0,
      ...initialStatistics
    }

    this.initializeDefaultAchievements()
    this.setupEventListeners()
  }

  /**
   * 初始化默认成就
   */
  private initializeDefaultAchievements(): void {
    const defaultAchievements: Achievement[] = [
      // 分数相关成就
      {
        id: 'first_score',
        name: '初出茅庐',
        description: '获得第一分',
        icon: 'score-1',
        category: AchievementCategory.SCORE,
        condition: { type: 'score', value: 1, operator: 'gte' },
        reward: { type: 'coins', value: 10, description: '获得10金币' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 1
      },
      {
        id: 'score_1000',
        name: '千分达人',
        description: '单局得分达到1000分',
        icon: 'score-1000',
        category: AchievementCategory.SCORE,
        condition: { type: 'score', value: 1000, operator: 'gte' },
        reward: { type: 'coins', value: 50, description: '获得50金币' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 1000
      },
      {
        id: 'score_5000',
        name: '分数大师',
        description: '单局得分达到5000分',
        icon: 'score-5000',
        category: AchievementCategory.SCORE,
        condition: { type: 'score', value: 5000, operator: 'gte' },
        reward: { type: 'character', value: 'speedster', description: '解锁疾风角色' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 5000
      },
      {
        id: 'score_10000',
        name: '传奇跑者',
        description: '单局得分达到10000分',
        icon: 'score-10000',
        category: AchievementCategory.SCORE,
        condition: { type: 'score', value: 10000, operator: 'gte' },
        reward: { type: 'title', value: '传奇跑者', description: '获得传奇跑者称号' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 10000
      },

      // 距离相关成就
      {
        id: 'distance_100',
        name: '百米冲刺',
        description: '跑步距离达到100米',
        icon: 'distance-100',
        category: AchievementCategory.DISTANCE,
        condition: { type: 'distance', value: 100, operator: 'gte' },
        reward: { type: 'coins', value: 20, description: '获得20金币' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 100
      },
      {
        id: 'distance_1000',
        name: '千米长跑',
        description: '跑步距离达到1000米',
        icon: 'distance-1000',
        category: AchievementCategory.DISTANCE,
        condition: { type: 'distance', value: 1000, operator: 'gte' },
        reward: { type: 'coins', value: 100, description: '获得100金币' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 1000
      },
      {
        id: 'distance_5000',
        name: '马拉松选手',
        description: '跑步距离达到5000米',
        icon: 'distance-5000',
        category: AchievementCategory.DISTANCE,
        condition: { type: 'distance', value: 5000, operator: 'gte' },
        reward: { type: 'character', value: 'jumper', description: '解锁跳跃者角色' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 5000
      },

      // 收集相关成就
      {
        id: 'coins_100',
        name: '小富翁',
        description: '收集100枚金币',
        icon: 'coins-100',
        category: AchievementCategory.COLLECTION,
        condition: { type: 'coins', value: 100, operator: 'gte' },
        reward: { type: 'coins', value: 50, description: '获得50金币奖励' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 100
      },
      {
        id: 'coins_500',
        name: '金币收藏家',
        description: '收集500枚金币',
        icon: 'coins-500',
        category: AchievementCategory.COLLECTION,
        condition: { type: 'coins', value: 500, operator: 'gte' },
        reward: { type: 'character', value: 'collector', description: '解锁收集者角色' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 500
      },
      {
        id: 'powerups_50',
        name: '道具专家',
        description: '收集50个道具',
        icon: 'powerups-50',
        category: AchievementCategory.COLLECTION,
        condition: { type: 'powerups', value: 50, operator: 'gte' },
        reward: { type: 'coins', value: 200, description: '获得200金币' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 50
      },

      // 生存相关成就
      {
        id: 'survival_60',
        name: '生存专家',
        description: '单局生存60秒',
        icon: 'survival-60',
        category: AchievementCategory.SURVIVAL,
        condition: { type: 'survival', value: 60, operator: 'gte' },
        reward: { type: 'coins', value: 100, description: '获得100金币' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 60
      },
      {
        id: 'survival_300',
        name: '不死传说',
        description: '单局生存300秒',
        icon: 'survival-300',
        category: AchievementCategory.SURVIVAL,
        condition: { type: 'survival', value: 300, operator: 'gte' },
        reward: { type: 'character', value: 'tank', description: '解锁坦克角色' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 300
      },

      // 特殊成就
      {
        id: 'perfect_run',
        name: '完美跑者',
        description: '完成一次完美跑步（不受伤害）',
        icon: 'perfect-run',
        category: AchievementCategory.SPECIAL,
        condition: { type: 'games', value: 1, operator: 'gte' },
        reward: { type: 'coins', value: 500, description: '获得500金币' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 1
      },
      {
        id: 'character_collector',
        name: '角色收藏家',
        description: '解锁所有角色',
        icon: 'character-collector',
        category: AchievementCategory.CHARACTER,
        condition: { type: 'characters', value: 6, operator: 'gte' },
        reward: { type: 'character', value: 'ninja', description: '解锁忍者角色' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 6
      },
      {
        id: 'veteran_player',
        name: '资深玩家',
        description: '游戏100次',
        icon: 'veteran-player',
        category: AchievementCategory.SPECIAL,
        condition: { type: 'games', value: 100, operator: 'gte' },
        reward: { type: 'title', value: '资深玩家', description: '获得资深玩家称号' },
        isUnlocked: false,
        progress: 0,
        maxProgress: 100
      }
    ]

    defaultAchievements.forEach(achievement => {
      this.achievements.set(achievement.id, achievement)
    })
  }

  /**
   * 设置事件监听器
   */
  private setupEventListeners(): void {
    // 游戏结束时检查成就
    this.addEventListener(AchievementEventType.GAME_END, (event) => {
      this.updateStatistics(event)
      this.checkAllAchievements()
    })

    // 分数达成时检查相关成就
    this.addEventListener(AchievementEventType.SCORE_ACHIEVED, (event) => {
      this.checkScoreAchievements(event.value)
    })

    // 距离达成时检查相关成就
    this.addEventListener(AchievementEventType.DISTANCE_REACHED, (event) => {
      this.checkDistanceAchievements(event.value)
    })

    // 金币收集时检查相关成就
    this.addEventListener(AchievementEventType.COIN_COLLECTED, (event) => {
      this.statistics.totalCoins += event.value
      this.checkCollectionAchievements()
    })

    // 道具收集时检查相关成就
    this.addEventListener(AchievementEventType.POWERUP_COLLECTED, (event) => {
      this.statistics.powerUpsCollected += event.value
      this.checkCollectionAchievements()
    })

    // 角色解锁时检查相关成就
    this.addEventListener(AchievementEventType.CHARACTER_UNLOCKED, (event) => {
      this.statistics.charactersUnlocked += event.value
      this.checkCharacterAchievements()
    })
  }

  /**
   * 添加事件监听器
   */
  addEventListener(eventType: AchievementEventType, callback: (event: AchievementEvent) => void): void {
    if (!this.eventListeners.has(eventType)) {
      this.eventListeners.set(eventType, [])
    }
    this.eventListeners.get(eventType)!.push(callback)
  }

  /**
   * 触发事件
   */
  triggerEvent(event: AchievementEvent): AchievementUnlockResult[] {
    const listeners = this.eventListeners.get(event.type) || []
    const unlockedAchievements: AchievementUnlockResult[] = []

    listeners.forEach(callback => {
      try {
        callback(event)
      } catch (error) {
        console.error('成就事件处理错误:', error)
      }
    })

    // 检查是否有新解锁的成就
    this.achievements.forEach(achievement => {
      if (!achievement.isUnlocked && this.checkAchievementCondition(achievement)) {
        achievement.isUnlocked = true
        achievement.unlockedAt = new Date()
        unlockedAchievements.push({
          achievement,
          isNewlyUnlocked: true,
          reward: achievement.reward
        })
      }
    })

    return unlockedAchievements
  }

  /**
   * 更新统计数据
   */
  private updateStatistics(event: AchievementEvent): void {
    switch (event.type) {
      case AchievementEventType.GAME_END:
        this.statistics.gamesPlayed += 1
        if (event.metadata) {
          const { score, distance, survivalTime, isPerfectRun } = event.metadata
          this.statistics.totalScore += score || 0
          this.statistics.totalDistance += distance || 0
          this.statistics.highestScore = Math.max(this.statistics.highestScore, score || 0)
          this.statistics.longestDistance = Math.max(this.statistics.longestDistance, distance || 0)
          this.statistics.maxSurvivalTime = Math.max(this.statistics.maxSurvivalTime, survivalTime || 0)
          if (isPerfectRun) {
            this.statistics.perfectRuns += 1
          }
        }
        break
      case AchievementEventType.JUMP_PERFORMED:
        this.statistics.consecutiveJumps += event.value
        break
      case AchievementEventType.SLIDE_PERFORMED:
        this.statistics.slidingDistance += event.value
        break
    }
  }

  /**
   * 检查成就条件
   */
  private checkAchievementCondition(achievement: Achievement): boolean {
    const condition = achievement.condition
    let currentValue = 0

    switch (condition.type) {
      case 'score':
        currentValue = this.statistics.highestScore
        break
      case 'distance':
        currentValue = this.statistics.longestDistance
        break
      case 'coins':
        currentValue = this.statistics.totalCoins
        break
      case 'games':
        currentValue = this.statistics.gamesPlayed
        break
      case 'powerups':
        currentValue = this.statistics.powerUpsCollected
        break
      case 'characters':
        currentValue = this.statistics.charactersUnlocked
        break
      case 'survival':
        currentValue = this.statistics.maxSurvivalTime
        break
      default:
        return false
    }

    // 更新进度
    achievement.progress = Math.min(currentValue, achievement.maxProgress)

    // 检查条件
    switch (condition.operator) {
      case 'gte':
        return currentValue >= condition.value
      case 'lte':
        return currentValue <= condition.value
      case 'eq':
        return currentValue === condition.value
      case 'gt':
        return currentValue > condition.value
      case 'lt':
        return currentValue < condition.value
      default:
        return false
    }
  }

  /**
   * 检查所有成就
   */
  private checkAllAchievements(): void {
    this.achievements.forEach(achievement => {
      if (!achievement.isUnlocked) {
        this.checkAchievementCondition(achievement)
      }
    })
  }

  /**
   * 检查分数相关成就
   */
  private checkScoreAchievements(score: number): void {
    this.achievements.forEach(achievement => {
      if (!achievement.isUnlocked && 
          achievement.category === AchievementCategory.SCORE &&
          achievement.condition.type === 'score') {
        this.checkAchievementCondition(achievement)
      }
    })
  }

  /**
   * 检查距离相关成就
   */
  private checkDistanceAchievements(distance: number): void {
    this.achievements.forEach(achievement => {
      if (!achievement.isUnlocked && 
          achievement.category === AchievementCategory.DISTANCE &&
          achievement.condition.type === 'distance') {
        this.checkAchievementCondition(achievement)
      }
    })
  }

  /**
   * 检查收集相关成就
   */
  private checkCollectionAchievements(): void {
    this.achievements.forEach(achievement => {
      if (!achievement.isUnlocked && 
          achievement.category === AchievementCategory.COLLECTION) {
        this.checkAchievementCondition(achievement)
      }
    })
  }

  /**
   * 检查角色相关成就
   */
  private checkCharacterAchievements(): void {
    this.achievements.forEach(achievement => {
      if (!achievement.isUnlocked && 
          achievement.category === AchievementCategory.CHARACTER) {
        this.checkAchievementCondition(achievement)
      }
    })
  }

  /**
   * 获取所有成就
   */
  getAllAchievements(): Achievement[] {
    return Array.from(this.achievements.values())
  }

  /**
   * 获取已解锁的成就
   */
  getUnlockedAchievements(): Achievement[] {
    return this.getAllAchievements().filter(achievement => achievement.isUnlocked)
  }

  /**
   * 获取未解锁的成就
   */
  getLockedAchievements(): Achievement[] {
    return this.getAllAchievements().filter(achievement => !achievement.isUnlocked)
  }

  /**
   * 根据类别获取成就
   */
  getAchievementsByCategory(category: AchievementCategory): Achievement[] {
    return this.getAllAchievements().filter(achievement => achievement.category === category)
  }

  /**
   * 获取成就进度
   */
  getAchievementProgress(achievementId: string): { progress: number; maxProgress: number; percentage: number } {
    const achievement = this.achievements.get(achievementId)
    if (!achievement) {
      return { progress: 0, maxProgress: 1, percentage: 0 }
    }

    const percentage = achievement.maxProgress > 0 
      ? (achievement.progress / achievement.maxProgress) * 100 
      : 0

    return {
      progress: achievement.progress,
      maxProgress: achievement.maxProgress,
      percentage: Math.min(percentage, 100)
    }
  }

  /**
   * 获取统计数据
   */
  getStatistics(): GameStatistics {
    return { ...this.statistics }
  }

  /**
   * 手动更新统计数据
   */
  updateGameStatistics(newStats: Partial<GameStatistics>): void {
    this.statistics = { ...this.statistics, ...newStats }
  }

  /**
   * 序列化成就数据
   */
  serialize(): any {
    return {
      achievements: Array.from(this.achievements.entries()).map(([id, achievement]) => ({
        id,
        isUnlocked: achievement.isUnlocked,
        unlockedAt: achievement.unlockedAt,
        progress: achievement.progress
      })),
      statistics: this.statistics
    }
  }

  /**
   * 反序列化成就数据
   */
  deserialize(data: any): void {
    if (data.statistics) {
      this.statistics = { ...this.statistics, ...data.statistics }
    }

    if (data.achievements && Array.isArray(data.achievements)) {
      data.achievements.forEach((achievementData: any) => {
        const achievement = this.achievements.get(achievementData.id)
        if (achievement) {
          achievement.isUnlocked = achievementData.isUnlocked || false
          achievement.unlockedAt = achievementData.unlockedAt ? new Date(achievementData.unlockedAt) : undefined
          achievement.progress = achievementData.progress || 0
        }
      })
    }
  }

  /**
   * 重置所有成就
   */
  resetAllAchievements(): void {
    this.achievements.forEach(achievement => {
      achievement.isUnlocked = false
      achievement.unlockedAt = undefined
      achievement.progress = 0
    })

    this.statistics = {
      totalScore: 0,
      totalDistance: 0,
      totalCoins: 0,
      gamesPlayed: 0,
      powerUpsCollected: 0,
      charactersUnlocked: 1,
      maxSurvivalTime: 0,
      highestScore: 0,
      longestDistance: 0,
      perfectRuns: 0,
      consecutiveJumps: 0,
      slidingDistance: 0
    }
  }
}